#include <string>

#include "../Api Headers/DataTree.hpp"

_BOF_ZIA_API_

DataTree::DataTree()
{

}

DataTree::~DataTree()
{
	this->clear();
}

DataTree::operator const std::string& () const
{
	return (this->mValue);
}

DataTree&               DataTree::operator = (const DataTree &dataTree)
{

	/*
	** cas: unDataTree["cle"] = branche;
	** remplace les sous-noeud/value/list de "cle"
	*/

	this->clear();
	this->mSubs = dataTree.mSubs;
	this->mValue = dataTree.mValue;
	this->mList = dataTree.mList;

	return (*this);
}

DataTree&               DataTree::operator = (const std::string &value)
{
	//cas: nimp["cle"] = "une valeur"
	this->mValue = value;
	return (*this);
}

DataTree&               DataTree::operator += (const DataTree &dataTree)
{
	/*
	** cas: nimp["cle"] += branche;
	** fusionne les List et Subs, je ne sais pas pour les Values (concat?)
	*/
	std::map<std::string, DataTree>::const_iterator it;

	for (std::list<std::string>::const_iterator listit = dataTree.mList.begin(); listit != dataTree.mList.end(); ++listit)
		this->mList.push_back((*listit));

	it = dataTree.mSubs.begin();
	while (it != dataTree.mSubs.end())
	{
		this->mSubs.insert(
			std::map<std::string, DataTree>::value_type((*it).first, (*it).second));
		++it;
	}
	return (*this);
}

const DataTree&         DataTree::operator [] (const std::string &key) const
{
	if (this->mSubs.find(key) != this->mSubs.end())
	{
		const DataTree tree;
		//this->mSubs.insert(std::map<std::string, DataTree>::value_type(key, tree));
		//ya un probleme de const
	}
	//	return (this->mSubs[key]); et donc probleme de retour aussi...
	return (*this);//retour factice
}

DataTree&               DataTree::operator [] (const std::string &key)
{
	//cas: nimp["cle"]["cle2"];
	if (this->mSubs.find(key) != this->mSubs.end())
	{
		DataTree tree;
		this->mSubs.insert(std::map<std::string, DataTree>::value_type(key, tree));
	}		
	return (this->mSubs[key]);
}

bool                    DataTree::operator == (const std::string &right) const
{	
	return (this->mValue == right ? true : false);
}

bool                    DataTree::operator != (const std::string &right) const
{
	return (this->mValue != right ? true : false);
}

const DataTree&         DataTree::c() const
{
	return (*this);
}

const std::string&      DataTree::v() const
{
	return (this->mValue);
}

bool                    DataTree::has(const std::string &key) const
{
	if (this->mSubs.find(key) != this->mSubs.end())
		return true;
	else
		return false;
}

const DataTree&         DataTree::get(const std::string &key) const
{
	std::map<std::string, DataTree>::const_iterator it;

	it = this->mSubs.find(key);
	if (it != this->mSubs.end())
		return (*it).second;
	else
	{
		//a implementer: retour d'un datatree vide
		return (*this);
	}
}

void                    DataTree::clear()
{
	this->mValue.clear();
	this->mSubs.erase(this->mSubs.begin(), this->mSubs.end());
	this->mList.erase(this->mList.begin(), this->mList.end());
	return ;
}

void                    DataTree::print(std::ostream &out, int indentLevel) const
{
	std::map<std::string, DataTree>::const_iterator it;
	std::string tab;

	for (int i = 0; i < indentLevel; i++)
		tab += "    ";

	it = this->mSubs.begin();
		out << tab << "Value : " << this->mValue << std::endl;

//ici, afficher le contenu de mList

	while (it != this->mSubs.end())
	{
		out << tab << "Array[";
		out << (*it).first << "]: " << std::endl;
		(*it).second.print(out, indentLevel + 1);
		++it;
	}
	return ;
}

_EOF_ZIA_API_
